package examples;
/**
this software is under GNU GPL
@author: Jorge Alejandro Gutiérrez Orozco
compilation
    javac Cube.java
Ejecution
    appletviewer Hola.html
*/

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;
import java.awt.Polygon;
 
/* Represents a point in space */
 
class Point{
 
public double x;
 
public double y;
 
public double z;
 
Point(){ this.x=0; this.y=0; this.z=0; }
 
Point(double x,double y, double z){ this.x=x; this.y=y; this.z=z; }
 
/* for move it at origin */
 
int getXCoordinate(){return Cube.origin + (int)this.x;}
 
int getYCoordinate(){return Cube.origin - (int)this.y;}
 
int getZCoordinate(){return 0;} /* projection on XY plane*/
 
}
 
class Face{
 
Point p1,p2,p3,p4;
 
Polygon side= new Polygon();
 
Face(){}
 
Face(Point p1,Point p2,Point p3,Point p4){
 
this.p1=p1;this.p2=p2;this.p3=p3;this.p4=p4;
 
this.side.addPoint(p1.getXCoordinate(),p1.getYCoordinate());
 
this.side.addPoint(p2.getXCoordinate(),p2.getYCoordinate());
 
this.side.addPoint(p3.getXCoordinate(),p3.getYCoordinate());
 
this.side.addPoint(p4.getXCoordinate(),p4.getYCoordinate());
 
}
 
public void drawFace(Graphics g){ g.fillPolygon(side); }
 
public boolean isVisible(){
 
Point aux1, aux2;
 
aux1 = new Point(p2.x-p1.x, p2.y-p1.y, p2.z-p1.z); // p1->p2
 
aux2 = new Point(p4.x-p1.x, p4.y-p1.y, p4.z-p1.z); // p1->p4
 
if((aux1.x*aux2.y - aux1.y*aux2.x) > 0)
 
return true;
 
return false;
 
}
 
}
 
public class Cube extends Applet implements
 
Runnable, MouseMotionListener{
 
Thread luxury;
 
static Point[] vertex = new Point[8]; // Cube vertexes
 
static int maxSize =300; // screen size
 
static int origin = maxSize/2; // (0,0)
 
static int xMouseP=0, yMouseP =0; // X and Y mouse's positions
 
int xAux , yAux ; // old X and Y mouse's positions
 
int module = 50; // length of lines of cube.
 
Image canvasAux;
 
Graphics backBuffer;
 
public void init(){
 
setSize(maxSize,maxSize);
 
setBackground( new Color(0.2f,0.6f,0.1f,1.0f) );
 
addMouseMotionListener(this);
 
/*Initial coordinates of eight vertex
module is half the length of the cube*/
 
int[] coordX = new int[]{-module,module,module,-module,-module,module,module,-module};
 
int[] coordY = new int[]{-module,-module,module,module,-module,-module,module,module};
 
int[] coordZ = new int[]{module,module,module,module,-module,-module,-module,-module};
 
canvasAux = createImage(500,500);
 
backBuffer = canvasAux.getGraphics();
 
for(int i =0; i<vertex.length; i++){
 
vertex[i] = new Point(coordX[i],coordY[i],coordZ[i]);
 
}
 
}
 
public void start(){
 
try { luxury = new Thread(this); luxury.start(); }
 
catch (Exception e){}
 
}
 
public void run() {}
 
public void stop(){}
 
public void paint(Graphics g){
 
/* Cube's points.
Requires four points to create a face,
requires six faces to create a cube.*/
 
int[] pts1 = new int[]{0,1,5,0,0,3};
 
int[] pts2 = new int[]{1,5,4,3,4,2};
 
int[] pts3 = new int[]{2,6,7,7,5,6};
 
int[] pts4 = new int[]{3,2,6,4,1,7};
 
Color[] colorRGB = new Color[]{ Color.black, Color.blue,Color.orange,
 
Color.pink,Color.red, Color.yellow};
 
Face[] faces = new Face[6];
 
backBuffer.clearRect(0,0,500,500);
 
for(int i=0; i<6; i++){
 
backBuffer.setColor(colorRGB[i]);
 
faces[i] = new 
 
Face(vertex[pts1[i]],vertex[pts2[i]],vertex[pts3[i]],vertex[pts4[i]]);
 
if(faces[i].isVisible()){
 
faces[i].drawFace(backBuffer);
 
}
 
}
 
g.drawImage(canvasAux,0,0,this);
 
g.drawString(" Touche ", 30,30);
 
g.drawString(" X " + xMouseP, 30,50);
 
g.drawString(" Y " + yMouseP, 30,65);
 
return;
 
}
 
public void update(Graphics g){ paint(g); }
 
public void destroy(){
 
try {Thread.sleep(1500);}
 
catch (InterruptedException e) {
 
System.out.println("Exception in sleep");
 
}
 
}
 
/* Rotate each vertex of cube over X, Y and Z axis */
 
void rota(double angleTeta, double anglePhi, double anglePsi) {
 
double teta= Math.toRadians(angleTeta);
 
double phi= Math.toRadians(anglePhi);
 
double psi= Math.toRadians(anglePsi);
 
Point pAux = new Point();
 
Point pAux1 = new Point();
 
Point pAux2 = new Point();
 
for(int i =0; i<8; i++){
 
/* Rotating over x */
 
pAux1.x = vertex[i].x;
 
pAux1.y= vertex[i].y * Math.cos(teta) + vertex[i].z * (-Math.sin(teta));
 
pAux1.z = vertex[i].y * Math.sin(teta) + vertex[i].z * Math.cos(teta);
 
/* Rotating over y */
 
pAux2.x = pAux1.x * Math.cos(phi) + pAux1.z * Math.sin(phi);
 
pAux2.y = pAux1.y;
 
pAux2.z = pAux1.x * (-Math.sin(phi)) + pAux1.z * Math.cos(phi);
 
/* Rotating over z */
 
pAux.x= pAux2.x * Math.cos(psi) + pAux2.y * (-Math.sin(psi));
 
pAux.y = pAux2.x * Math.sin(psi) + pAux2.y * Math.cos(psi);
 
pAux.z= pAux2.z;
 
/* new position */
 
vertex[i].x = pAux.x;
 
vertex[i].y = pAux.y;
 
vertex[i].z = pAux.z;
 
}
 
}
 
/* For move the cube over X and Y axis */
 
public void mouseDragged( MouseEvent e ){
 
/* old coordinates */
 
xAux = xMouseP;
 
yAux = yMouseP;
 
/* new coordinates */
 
xMouseP = e.getX();
 
yMouseP = e.getY();
 
if(yMouseP > yAux){ rota(2,0,0); }
 
if(yMouseP < yAux){ rota(-2,0,0); }
 
if(xMouseP > xAux){ rota(0,2,0); }
 
if(xMouseP < xAux){ rota(0,-2,0); }
 
repaint();
 
e.consume();
 
}
 
public void mouseMoved( MouseEvent e ) { }
 
}